package com.jgp.timing.component;

import com.jgp.timing.thread.JobThread;
import lombok.extern.log4j.Log4j2;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.function.Consumer;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2019/4/1
 */
@Log4j2
@Component
public class QuartzManager {
    
    private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
    
    private static final String JOB_DEFAULT_GROUP_NAME = "JOB_DEFAULT_GROUP_NAME";
    
    private static final String TRIGGER_DEFAULT_GROUP_NAME = "TRIGGER_DEFAULT_GROUP_NAME";
    
    @Autowired
    private Scheduler scheduler;
    
    /*
     *  增加定时任务
     */
    public boolean addJob(String jobName, String cronExp, Consumer<JobExecutionContext> consumer) {
        boolean result = false;
        if (!CronExpression.isValidExpression(cronExp)) {
            log.error("Illegal cron expression format({})", cronExp);
            return result;
        }
        try {
            JobDetail jobDetail = JobBuilder.newJob().withIdentity(new JobKey(jobName, JOB_DEFAULT_GROUP_NAME))
                                            .ofType(JobThread.class)
                                            .build();
            jobDetail.getJobDataMap().put("apply",consumer);
            Trigger trigger = TriggerBuilder.newTrigger()
                                            .forJob(jobDetail)
                                            .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
                                            .withIdentity(new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME))
                                            .build();
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("QuartzManager add job failed");
        }
        return result;
    }
    
    /*
     *  更新定时任务
     */
    public boolean updateJob(String jobName, String cronExp) {
        boolean result = false;
        if (!CronExpression.isValidExpression(cronExp)) {
            log.error("Illegal cron expression format({})", cronExp);
            return result;
        }
        JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);
        TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME);
        try {
            if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
                JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                Trigger newTrigger = TriggerBuilder.newTrigger()
                                                   .forJob(jobDetail)
                                                   .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
                                                   .withIdentity(new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME))
                                                   .build();
                scheduler.rescheduleJob(triggerKey, newTrigger);
                result = true;
            } else {
                log.error("update job name:{},group name:{} or trigger name:{},group name:{} not exists..",
                             jobKey.getName(), jobKey.getGroup(), triggerKey.getName(), triggerKey.getGroup());
            }
        } catch (SchedulerException e) {
            log.error(e.getMessage(), e);
            log.error("update job name:{},group name:{} failed!", jobKey.getName(), jobKey.getGroup());
        }
        return result;
    }
    
    /*
     * 删除定时任务
     */
    public boolean deleteJob(String jobName) {
        boolean result = false;
        JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);
        try {
            if (scheduler.checkExists(jobKey)) {
                result = scheduler.deleteJob(jobKey);
            } else {
                log.error("delete job name:{},group name:{} not exists.", jobKey.getName(), jobKey.getGroup());
            }
        } catch (SchedulerException e) {
            log.error(e.getMessage(), e);
            log.error("delete job name:{},group name:{} failed!", jobKey.getName(), jobKey.getGroup());
        }
        return result;
    }
    
    public boolean hasJob(String jobName) {
        JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);
        try {
            return scheduler.checkExists(jobKey);
        } catch (SchedulerException e) {
            return false;
        }
    }
}
